package com.iwhalecloud.bss.kite.cucc.web.filter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSONObject;
import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.cucc.web.ResponseExceptionHandler;
import com.ztesoft.zsmart.core.log.ZSmartLogger;

public class CrossDomainCORSFilter implements Filter {
    private static final ZSmartLogger LOGGER = ZSmartLogger.getLogger(ResponseExceptionHandler.class);

    /**
     * 自定义黑名单
     */
    private List<String> blackOriginList = new ArrayList<>();

    /**
     * 自定义白名单
     * add by ma.junjun
     * 2022-01-22
     * 避免出现正常访问，被限制黑名单的情况
     */

    private List<String> whiteOriginList =Arrays.asList("https://10.124.225.94","10.124.225.94","https://tt.unicom.local","tt.unicom.local","https://pre.tt.unicom.local","pre.tt.unicom.local","http://tt.wo.cn","tt.wo.cn");

    /**
     * 默认黑名单
     */
    private static final List<String> BLACK_ORIGIN_LIST_DEFAULT = Arrays.asList("baidu", "google", "sogou", "qq",
        "soso");

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        String referer = Optional.ofNullable(httpRequest.getHeader("Referer")).orElse("");
        String host = Optional.ofNullable(httpRequest.getHeader("Host")).orElse("");
        String http="https://";
        String origin = httpRequest.getHeader("Origin");
        String referTemp ="";
        //modified by ma.junjun 安全漏洞处理 2022-01-22
        if (!KiteStringUtils.isEmpty(referer)) {
            referTemp = referer.substring(0, referer.indexOf("/", 15));
        }else if ( KiteStringUtils.isEmpty(referer)){
            referTemp =http+host;
        }else{
            referTemp = "*";
        }
        if (origin == null) {

            referer= referTemp;
            httpResponse.setHeader("Access-Control-Allow-Origin", referer);
            httpResponse.setHeader("Access-Control-Allow-Headers",
                "Origin, cd, x_requested_with, x-requested-with, Content-Type, Accept,X-Cookie,portalSessionId,cust-unifiedSessionId, token,authSessionId,auth-unifiedSessionId, XMLHttpRequest");
            httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
            httpResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,PUT,OPTIONS,DELETE");
        }
        else {
            if (isBlackOrigin(origin ,referTemp)) {
                LOGGER.debug("Not Allowed CORS Origin: {}", origin);
            }
            else {
                httpResponse.setHeader("Access-Control-Allow-Origin", origin);
                httpResponse.setHeader("Access-Control-Allow-Headers",
                    "Origin, cd, x_requested_with, x-requested-with, Content-Type, Accept, X-Cookie, portalSessionId, cust-unifiedSessionId, token, authSessionId, auth-unifiedSessionId");
                httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
                httpResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,PUT,OPTIONS,DELETE");
            }
        }
        if ("OPTIONS".equals(httpRequest.getMethod())) {
            httpResponse.setStatus(HttpServletResponse.SC_OK);
            return;
        }
        chain.doFilter(request, response);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        blackOriginList.addAll(BLACK_ORIGIN_LIST_DEFAULT);

        String blackOrigin = filterConfig.getInitParameter("blackOrigin");
        if (KiteStringUtils.isNotEmpty(blackOrigin)) {
            blackOriginList.addAll(Arrays.asList(blackOrigin.split(",")));
        }

        LOGGER.debug("**** CrossDomainCORSFilter Init Completed **");
        LOGGER.debug("**** BLACK_ORIGIN_LIST: {}", JSONObject.toJSONString(blackOriginList));
        LOGGER.debug("*************************************");
    }

    private Boolean isBlackOrigin(String origin,String refer) {
        String originLower = origin.toLowerCase();
        /**
         * add by ma.junjun
         * 2022-01-22
         * 如果origin的ip和refer中的ip不一致，则认为是黑名单
         * 如果是在白名单中，则直接返回true[白名单设置了测试，准生产，生产的地址]
         */

        for (String whiteOrigin : whiteOriginList) {
            if (originLower.contains(whiteOrigin)) {
                return false;
            }
        }
        if(!KiteStringUtils.equals(origin,refer)){
            return true;
        }
        for (String blackOrigin : blackOriginList) {
            if (originLower.contains(blackOrigin)) {
                return true;
            }
        }
        return false;
    }
}
